package com.usefullc.system.controller;

import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.usefullc.common.constants.SystemConstant;
import com.usefullc.system.entity.WebResult;
import com.usefullc.system.service.component.SystemConfigComponent;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 专门处理参数问题的异常
 */
@RestControllerAdvice
public class ResponseExceptionHandler  {

    private static final Logger logger = LoggerFactory.getLogger(ResponseExceptionHandler.class);

    @Autowired
    private SystemConfigComponent systemConfigComponent;

    @ResponseBody
    @ExceptionHandler
    public WebResult exceptionHandler(HttpServletRequest request, Throwable e) {

        WebResult webResult = new WebResult(false, SystemConstant.ResponseCode.SYSTEM_ERROR);
        if(e.getCause() instanceof InvalidFormatException){
//            InvalidFormatException invalidFormatException = (InvalidFormatException) e;
            String message = ((InvalidFormatException) e.getCause()).getOriginalMessage();
//            if (StringUtils.isNotEmpty(message)) {
//                String token = "through reference chain: ";
//                int tokenIndex = message.indexOf(token);
//                if(tokenIndex != 0){
//                    message.substring(tokenIndex+token.length(),message.length()-1);
//
//                }
//            }
            webResult.setMessage(message);
//            webResult.setMessage("数据输入格式有问题");
        }else{
            webResult.setMessage(e.getMessage());
        }
        if (!systemConfigComponent.isProd()) {
            webResult.setData(ExceptionUtils.getStackTrace(e));
        }
        logger.error(ExceptionUtils.getStackTrace(e));
        return webResult;
    }

    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public WebResult exceptionHandler(HttpServletRequest request, MethodArgumentNotValidException e) {
        WebResult webResult = new WebResult(false, SystemConstant.ResponseCode.SYSTEM_ERROR);

        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        List<String> errMessages = allErrors.stream().map(data -> data.getDefaultMessage()).collect(Collectors.toList());

        //只处理第一个消息
//        FieldError fieldError1 = e.getBindingResult().getFieldError();
//        if(fieldError1 != null){
//            webResult.setMessage(fieldError1.getDefaultMessage());
//        }
        webResult.setMessage(StringUtils.join(errMessages,"\n"));
        if (!systemConfigComponent.isProd()) {
            webResult.setData(ExceptionUtils.getStackTrace(e));
        }
        logger.error(ExceptionUtils.getStackTrace(e));
        return webResult;
//        return null;
    }

    @RequestMapping(path = "/error")
    public WebResult error(HttpServletRequest request, Exception ex) {
        WebRequest requestAttributes = new ServletWebRequest(request);
//        Map<String, Object> errorAttributes = this.errorAttributes.getErrorAttributes(requestAttributes, false);
        Map<String, Object> map = new HashMap<>();
//        map.put("request path", errorAttributes.get("path"));
        map.put("request query", request.getQueryString());
//        map.put("errInfo",errorAttributes);
//        map.put("status", request.getAttribute("javax.servlet.error.status_code"));
//        map.put("reason", request.getAttribute("javax.servlet.error.message"));
        WebResult webResult = new WebResult(false, SystemConstant.ResponseCode.SYSTEM_ERROR);
        //只处理第一个消息
//        webResult.setData(errorAttributes);
        logger.error("system error={}",map);
        return webResult;
    }
//
}
